package com.example.base_model.view

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.annotation.IdRes
import androidx.annotation.Nullable
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import com.blankj.utilcode.util.LogUtils
import com.example.base_model.R
import com.example.base_model.dialog.LoadingCallback
import com.example.base_model.dialog.LoadingManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

/**
 * @Author jiangKunKun
 * @CreateDate 2025/6/23
 * @Description
 * @SpittingGrooves
 */
abstract class BaseFragment <VD : ViewDataBinding> : Fragment(), LoadingCallback {
    protected lateinit var mBinding: VD

    /**
     * 返回键
     */
    private var backPressedCallback: OnBackPressedCallback? = null
    /**
     * 懒加载
     */
    private var hasLazyLoaded = false
    /**
     * 当前上下文实例
     */
    protected lateinit var mActivity: Activity
    override fun onCreate(@Nullable savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.mActivity = requireActivity()
        LogUtils.d("当前Fragment是 ${this::class.simpleName} \n${this::class.java.name}")
        // 之前要做的
        beforeSetContent()

        // 默认启用返回监听
        backPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (enableBackPress()) {
                    onBackPress()
                }
            }
        }
        activity?.onBackPressedDispatcher?.addCallback(this, backPressedCallback!!)
    }

    /**
     * 可重写的返回按键处理方法
     */
    protected open fun onBackPress() {
        findNavController().popBackStack() // 执行默认返回
    }

    /**
     * 是否启用返回按键
     */
    protected open fun enableBackPress(): Boolean {
        return true // 默认启用返回按键
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        hasLazyLoaded = false // 每次视图创建时重置
        if (!::mBinding.isInitialized) { // 检查是否已初始化
            mBinding = DataBindingUtil.inflate(inflater, attachLayoutRes(), container, false)
        }

        val parent = mBinding.root.parent as? ViewGroup // 移除已有的父视图
        parent?.removeView(mBinding.root)

        return mBinding.root
    }

    // 在 onActivityCreated 或 onViewCreated 中
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            var isFirstTimeStarted = true // 保证只执行一次懒加载
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                // 当 Fragment 进入 STARTED 状态时执行
                if (isFirstTimeStarted) {
                    onLazyLoad() // 你的懒加载方法
                    isFirstTimeStarted = false
                }
                // 如果 onLazyLoad 不是一次性的，而是每次 STARTED 都要做某事，可以去掉 isFirstTimeStarted
            }
        }
        // 主要传递 savedInstanceState
        init(savedInstanceState)
        // 初始化各种监听
        initObservers()
        // 初始化点击事件
        initClickEvents()
        // 初始化基础数据
        initData()
    }

    /**
     * 之前要做的
     */
    protected open fun beforeSetContent() {}

    /**
     * 主要传递 savedInstanceState
     */
    protected open fun init(savedInstanceState: Bundle?) {}

    /**
     * 初始化各种监听
     */
    protected abstract fun initObservers()

    /**
     * 初始化点击事件
     */
    protected abstract fun initClickEvents()

    /**
     * 初始化基础数据
     */
    protected abstract fun initData()

    /**
     * 初始化布局
     */
    protected abstract fun attachLayoutRes(): Int

    /**
     * 懒加载
     */
    protected fun onLazyLoad() {}

    /**
     * UI 更新：使用 Lifecycle.State.STARTED - 界面可见时更新 UI
     * 高精度任务：使用 Lifecycle.State.RESUMED - 前台运行时执行
     * 后台任务：考虑使用 Lifecycle.State.CREATED，但需谨慎评估需求
     */
    protected inline fun launchAndCollect(crossinline block: suspend CoroutineScope.() -> Unit) {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                block()
            }
        }
    }

    /**
     * 可选传入任意 Lifecycle.State
     * UI 更新：使用 Lifecycle.State.STARTED - 界面可见时更新 UI
     * 高精度任务：使用 Lifecycle.State.RESUMED - 前台运行时执行
     * 后台任务：考虑使用 Lifecycle.State.CREATED，但需谨慎评估需求
     */
    protected inline fun launchAndCollect(state: Lifecycle.State, crossinline block: suspend CoroutineScope.() -> Unit) {
        lifecycleScope.launch {
            repeatOnLifecycle(state) {
                block()
            }
        }
    }

    /**
     * 显示加载
     */
    override fun showLoading(msg: String) {
        context?.let {
            LoadingManager.showLoading(it, msg)
        }
    }

    /**
     * 关闭加载
     */
    override fun hideLoading() {
        LoadingManager.dismissLoading()
    }

    /**
     * 页面跳转
     */
    fun goActivity(cls: Class<*>) {
        startActivity(Intent(mActivity, cls))
    }

    /**
     * 页面跳转携带参数
     */
    fun goActivity(cls: Class<*>, bundle: Bundle) {
        val intent = Intent(requireActivity(), cls)
        intent.putExtras(bundle)
        startActivity(intent)
    }

    /**
     * 导航到指定的目标Fragment，使用Safe Args生成的NavDirections对象
     * 此方法会应用默认的Fragment切换动画效果
     *
     * @param directions 通过Safe Args生成的导航方向对象，包含目标Fragment和传递的参数
     * @see androidx.navigation.NavDirections
     * @see createDefaultNavOptions
     */
    protected fun navigate(directions: androidx.navigation.NavDirections) {
        val navController = findNavController()
        val navOptions = createDefaultNavOptions()
        navController.navigate(directions, navOptions)
    }

    /**
     * 导航到指定的目标Fragment，使用action ID和可选的参数Bundle
     * 此方法会应用默认的Fragment切换动画效果
     *
     * @param actionId 导航图中定义的action资源ID
     * @param args 可选的Bundle参数，用于向目标Fragment传递数据
     * @see androidx.navigation.NavController.navigate
     * @see createDefaultNavOptions
     */
    protected fun navigate(@IdRes actionId: Int, args: Bundle? = null) {
        val navController = findNavController()
        val navOptions = createDefaultNavOptions()
        navController.navigate(actionId, args, navOptions)
    }

    /**
     * 创建默认的导航选项，包含统一的Fragment切换动画
     * 定义了进入、退出、返回时的动画效果，确保整个应用导航体验的一致性
     *
     * @return 配置了默认动画的NavOptions对象
     * @see androidx.navigation.NavOptions
     */
    private fun createDefaultNavOptions(): NavOptions {
        return NavOptions.Builder()
            .setEnterAnim(R.anim.slide_in_right)      // 新Fragment进入动画
            .setExitAnim(R.anim.slide_out_left)       // 当前Fragment退出动画
            .setPopEnterAnim(R.anim.slide_in_left)    // 返回时新Fragment进入动画
            .setPopExitAnim(R.anim.slide_out_right)   // 返回时当前Fragment退出动画
            .build()
    }

    /**
     * 移除指定Fragment
     * @param targetFragmentId 要移除的目标Fragment ID
     */
    protected fun removeSpecificFragment(@IdRes targetFragmentId: Int) {
        try {
            findNavController().popBackStack(targetFragmentId, inclusive = true)
        } catch (e: IllegalArgumentException) {
            // Fragment不存在于回退栈中
            LogUtils.d("Fragment $targetFragmentId 不存在于回退栈中")
        } catch (e: Exception) {
            LogUtils.d("移除Fragment失败: ${e.message}")
        }
    }

    /**
     * 安全地跨导航图移除指定Fragment
     * @param targetFragmentId 要移除的目标Fragment ID
     * @param navHostId 导航宿主ID
     */
    protected fun safelyRemoveFragmentAcrossGraphs(
        @IdRes targetFragmentId: Int,
        @IdRes navHostId: Int
    ) {
        try {
            val navController = requireActivity().findNavController(navHostId)
            // 先检查当前目的地是否为目标Fragment
            if (navController.currentDestination?.id == targetFragmentId) {
                // 如果当前就是目标Fragment，直接返回上一级
                navController.navigateUp()
            } else {
                // 尝试移除指定Fragment
                navController.popBackStack(targetFragmentId, inclusive = true)
            }
        } catch (e: IllegalArgumentException) {
            LogUtils.d("Fragment $targetFragmentId 不存在于回退栈中")
        } catch (e: Exception) {
            LogUtils.d("安全移除Fragment失败: ${e.message}")
        }
    }

    /**
     * 销毁View
     */
    override fun onDestroyView() {
        super.onDestroyView()
        if (::mBinding.isInitialized) {
            mBinding.unbind()
        }
        hideLoading() // 确保清理
    }

    /**
     * 销毁Fragment
     */
    override fun onDestroy() {
        super.onDestroy()
        LogUtils.d("当前Fragment是 ${this::class.simpleName} \n${this::class.java.name} \n已关闭")
    }

}